package top.lishuoboy.knife4j.openapi3.sb3.config;

import cn.hutool.core.collection.ListUtil;
import cn.hutool.core.map.MapUtil;
import io.swagger.v3.oas.models.OpenAPI;
import io.swagger.v3.oas.models.Operation;
import io.swagger.v3.oas.models.PathItem;
import io.swagger.v3.oas.models.Paths;
import org.springdoc.core.customizers.OpenApiLocaleCustomizer;
import org.springframework.context.annotation.Configuration;

import java.util.LinkedHashMap;
import java.util.Locale;
import java.util.Map;

@Configuration
public class OpenApiLocaleConfig implements OpenApiLocaleCustomizer {

    /** 【注意】knife4j-ui不显示 description */
    @Override
    public void customise(OpenAPI openApi, Locale locale) {

        // 1.配置Controller类（tags）排序（推荐按 name 或 description 排序）。默认按类@RequestMapping.path倒序
        ListUtil.sortByProperty(openApi.getTags(), "name");

        // 2.配置Controller方法（operation）排序。推荐按 summary 或 description 排序。默认按方法@RequestMapping.path倒序（但是空串在前）
        Map<String, Map.Entry<String, PathItem>> map = new LinkedHashMap<>();
        Paths paths = openApi.getPaths();
        for (Map.Entry<String, PathItem> pathItemEntry : paths.entrySet()) {
            operation(map, pathItemEntry, pathItemEntry.getValue().getGet(), "Get");
            operation(map, pathItemEntry, pathItemEntry.getValue().getPost(), "Post");
            operation(map, pathItemEntry, pathItemEntry.getValue().getPut(), "Put");
            operation(map, pathItemEntry, pathItemEntry.getValue().getDelete(), "Delete");
            operation(map, pathItemEntry, pathItemEntry.getValue().getHead(), "Head");
            operation(map, pathItemEntry, pathItemEntry.getValue().getPatch(), "Patch");
            operation(map, pathItemEntry, pathItemEntry.getValue().getOptions(), "Options");
            operation(map, pathItemEntry, pathItemEntry.getValue().getTrace(), "Trace");
        }
        map = MapUtil.sort(map);
        paths.clear();
        for (Map.Entry<String, Map.Entry<String, PathItem>> entry : map.entrySet()) {
            paths.put(entry.getValue().getKey(), entry.getValue().getValue());
        }
    }

    private void operation(Map<String, Map.Entry<String, PathItem>> map, Map.Entry<String, PathItem> entry, Operation operation, String method) {
        if (operation == null) {
            return;
        }
        String summary = operation.getSummary();
        summary += entry.getKey() + entry.getValue() + method;      // 防止summary/description重命被覆盖
        map.put(summary, entry);
    }
}